﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Windows.Input;
using System.Windows.Interop;

namespace WpfApp1
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private System.Windows.Threading.DispatcherTimer ShowTimer;
        private Int32 duration { get; set; }
        private Int32 durationIndex = -1;
        const Int32 LEFT_SCEONDS = 10;
        const Int32 SCEONDS_FACTORY = 60;
        private Boolean isFlash = false;

        Data data = new Data();

        NotifyIcon notifyIcon;

        private Int32 iconsIndex = 0;
        private Icon[] icons = new Icon[] {System.Drawing.Icon.ExtractAssociatedIcon(System.Windows.Forms.Application.ExecutablePath) , Properties.Resources.busy };

        public class Data {
            private Boolean isContinuousMode = true;
            private Boolean isAlwaysShow = true;
            private Int32 value1 = 25;
            private Int32 value2 = 5;

            public bool IsAlwaysShow { get => isAlwaysShow; set => isAlwaysShow = value; }

            public bool IsContinuousMode { get => isContinuousMode; set => isContinuousMode = value; }
            public int Value1 { get => value1; set => value1 = value; }
            public int Value2 { get => value2; set => value2 = value; }
        }

        public MainWindow()
        {
            this.DataContext = data;

            Event1Second();

            Event500Millieconds();

            this.Topmost = true;

            this.WindowStartupLocation = WindowStartupLocation.CenterScreen; // 设置窗口居中显示

            Loaded += OnWindowLoaded;

            initNotifyIcon();
        }

        private void Event1Second()
        {
            ShowTimer = new System.Windows.Threading.DispatcherTimer();

            ShowTimer.Tick += new EventHandler(EventHandler1Second);//起个Timer一直获取当前时间

            ShowTimer.Interval = new TimeSpan(0, 0, 0, 1, 0);

            ShowTimer.Start();
        }

        private void Event500Millieconds()
        {
            ShowTimer = new System.Windows.Threading.DispatcherTimer();

            ShowTimer.Tick += new EventHandler(EventHandler500Millieconds);//起个Timer一直获取当前时间

            ShowTimer.Interval = new TimeSpan(0, 0, 0, 0, 500);

            ShowTimer.Start();
        }

        public void initNotifyIcon(){
            this.notifyIcon = new NotifyIcon();
            this.notifyIcon.BalloonTipText = "时钟运行中...";
            this.notifyIcon.ShowBalloonTip(2000);
            this.notifyIcon.Text = "时钟运行中...";

            this.notifyIcon.Icon = icons[0];

            this.notifyIcon.Visible = true;
            //打开菜单项
            System.Windows.Forms.MenuItem open = new System.Windows.Forms.MenuItem("Switch");
            open.Click += new EventHandler(Switch);
            //退出菜单项
            System.Windows.Forms.MenuItem exit = new System.Windows.Forms.MenuItem("Exit");
            exit.Click += new EventHandler(Close);
            //关联托盘控件
            System.Windows.Forms.MenuItem[] childen = new System.Windows.Forms.MenuItem[] { open, exit };
            notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(childen);

            this.notifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler((o, e) =>
            {
                if (e.Button == MouseButtons.Left) this.Switch(o, e);
            });
        }

        private void Switch(object sender, EventArgs e)
        {
            Switch();
        }

        private void Close(object sender, EventArgs e)
        {
            doClose();
        }
        override protected void OnClosed(EventArgs e)
        {
            doClose();
        }

        private void doClose() {
            notifyIcon.Dispose();

            this.Close();
            System.Windows.Application current = System.Windows.Application.Current;
            if (current != null) current.Shutdown();
        }

        public void EventHandler1Second(object sender, EventArgs e)
        {
            this.ShowTime();
        }

        //ShowTime方法
        private void ShowTime()
        {
            if (duration == LEFT_SCEONDS + 1)
            {
                this.WindowState = WindowState.Normal;
                this.Topmost = true;
            }

            if (duration == 0)
            {
                if (ShowTimer.IsEnabled == true)
                {
                    ShowTimer.Stop();
                }
                if (isFlash == true) {
                    WindowExtensions.StopFlashingWindow(this);
                }
                if (data.IsContinuousMode == true)
                {
                    durationIndex = (durationIndex + 1) % 2;
                    Tick(getValueByIndex());
                }
            }
            else
            {
                duration -= 1;
            }

            updateTimeText();
        }

        public void EventHandler500Millieconds(object sender, EventArgs e) {
            iconFlashing();
        }

        private void iconFlashing() {
            iconsIndex = (iconsIndex + 1) % icons.Length;
            this.notifyIcon.Icon = icons[iconsIndex];            
        }

        private void updateTimeText() {
            this.timeText.Text = getTimeDisplay(duration);
        }

        private string getTimeDisplay(Int32 duration)
        {
            TimeSpan ts = new TimeSpan(0, 0, duration);
            int hours = ts.Hours;
            int minutes = ts.Minutes;
            int seconds = ts.Seconds;
            String splitSeconds = ":";

            string str = "";
            if (hours > 0)
            {
                str = hours + ":" + minutes + splitSeconds + seconds;
            }
            if (hours == 0 && minutes > 0)
            {
                if (seconds < 10)
                {
                    str = minutes + splitSeconds + "0" + seconds;
                }
                else
                {
                    str = minutes + splitSeconds + seconds;
                }
            }
            if (hours == 0 && minutes == 0)
            {
                str = seconds + "";
            }
            return str;
        }

        private void onValue1Click(object sender, RoutedEventArgs e)
        {
            durationIndex = 0;
            Tick(getValueByIndex());
        }

        private void onValue2Click(object sender, RoutedEventArgs e)
        {
            durationIndex = 1;
            Tick(getValueByIndex());
        }

        private void onResetClick(object sender, RoutedEventArgs e)
        {
            Reset();
        }

        private void Reset() {
            ShowTimer.Stop();
            duration = 0;
            durationIndex = 0;
            WindowExtensions.StopFlashingWindow(this);
            isFlash = false;
            updateTimeText();
        }

        private void Switch() {
            WindowState state = this.WindowState;
            switch (state){
                case WindowState.Minimized:
                    state = WindowState.Normal;
                    break;
                case WindowState.Normal:
                    state = WindowState.Minimized;
                    break;
            }

            this.WindowState = state;
        }

        private void setDuratonAndStartTimer(Int32 duration)
        {
            this.duration = duration;
            ShowTimer.Start();

            setWindowShow();
        }

        private void setWindowShow()
        {
            //只有工作时间才最小化
            if (data.IsAlwaysShow)
            {
                this.WindowState = WindowState.Normal;
            }
            else if (this.durationIndex == 0)
            {
                this.WindowState = WindowState.Minimized;
            }
        }

        //全局热键
        protected override void OnSourceInitialized(EventArgs e)
        {
            Hotkey.Regist(this, HotkeyModifiers.MOD_ALT | HotkeyModifiers.MOD_CONTROL , Key.D1, () =>
            {
                durationIndex = 0;
                Tick(getValueByIndex());
            });

            Hotkey.Regist(this, HotkeyModifiers.MOD_ALT | HotkeyModifiers.MOD_CONTROL, Key.D2, () =>
            {
                durationIndex = 1;
                Tick(getValueByIndex());
            });

            Hotkey.Regist(this, HotkeyModifiers.MOD_ALT | HotkeyModifiers.MOD_CONTROL, Key.R, () =>
            {
                Reset();
                setWindowShow(); 
            });

            Hotkey.Regist(this, HotkeyModifiers.MOD_ALT | HotkeyModifiers.MOD_CONTROL, Key.V, () =>
            {
                Switch();
            });
        }

        private void Tick(Int32 minus) {
            setDuratonAndStartTimer(minus * SCEONDS_FACTORY);
            WindowExtensions.FlashWindow(this);
            isFlash = true;
        }

        //窗体热键
        private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            switch (((System.Windows.Input.RoutedUICommand)e.Command).Text)
            {
                case "KValue1":
                    durationIndex = 0;
                    Tick(getValueByIndex());
                    break;
                case "KValue2":
                    durationIndex = 1;
                    Tick(getValueByIndex());
                    break;
                default:
                    return;
            }
        }

        private Int32 getValueByIndex() {
            Int32 value = 0;
            switch (durationIndex)
            {
                case 0:
                    value = data.Value1;
                    this.button1.Content = data.Value1 + " <";
                    this.button2.Content = data.Value2 + "  ";
                    break;
                case 1:
                    value = data.Value2;
                    this.button1.Content = data.Value1 + "  ";
                    this.button2.Content = data.Value2 + " <";
                    break;
            }

            return value;
        }

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void OnWindowLoaded(object sender, RoutedEventArgs e)
        {
            SetAsDesktopChild();
        }

        [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindowEx(IntPtr hP, IntPtr hC, string sC, string sW);


        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool EnumWindows(EnumedWindow lpEnumFunc, ArrayList lParam);

        public delegate bool EnumedWindow(IntPtr handleWindow, ArrayList handles);

        public static bool GetWindowHandle(IntPtr windowHandle, ArrayList windowHandles)
        {
            windowHandles.Add(windowHandle);
            return true;
        }

        private void SetAsDesktopChild()
        {
            ArrayList windowHandles = new ArrayList();
            EnumedWindow callBackPtr = GetWindowHandle;
            EnumWindows(callBackPtr, windowHandles);

            foreach (IntPtr windowHandle in windowHandles)
            {
                IntPtr hNextWin = FindWindowEx(windowHandle, IntPtr.Zero, "SHELLDLL_DefView", null);
                if (hNextWin != IntPtr.Zero)
                {
                    var interop = new WindowInteropHelper(this);
                    interop.EnsureHandle();
                    interop.Owner = hNextWin;
                }
            }
        }
    }
}
